﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ATM_Banking_Service.DAO
{
    public class CustomerDAO
    {
        private ATMServiceEntities _context;

        public bool Login(string id, string pin, out string token, out int errorCode)
        {
            var sercurity = new SercurityDAO();
            using (_context = Common.Utils.GetObjectContext())
            {
                var result =
                    _context.Customer.FirstOrDefault(
                        customer => customer.CustomerID.Equals(id) && customer.PIN.Equals(pin));
                    if (result != null)
                    {
                        if (result.Status=="Blocked")
                        {
                            errorCode = 11;
                            token = null;
                            return false;
                        }
                        token = sercurity.CreateToken(id);
                        errorCode = 0;
                        return true;
                    }
            }
            token = null;
            errorCode = 1;
            return false;
        }

        public bool Logout(string token)
        {          
            using (_context = Common.Utils.GetObjectContext())
            {
                var result = _context.Sercurity.FirstOrDefault(sercurity => sercurity.CustomerToken.Equals(token));
                if (result != null)
                {
                    result.Status = "Expired";
                    _context.SaveChanges();
                    return true;
                }
                return false;
            }
        }

        public int Withdraw(string token, long amount)
        {
            var sercurity = new SercurityDAO();
            bool isExpire = sercurity.ValidateToken(token);
            if (!isExpire)
            {
                string id = sercurity.GetIdByToken(token);
                using (_context = Common.Utils.GetObjectContext())
                {
                    var result = _context.Customer.FirstOrDefault(customer => customer.CustomerID.Equals(id));
                    if (result != null)
                    {
                        if ((result.Balance - amount) < 50000)
                        {
                            return 6;
                        }
                        result.Balance = result.Balance - amount;
                        _context.SaveChanges();
                        return 0;
                    }
                    return 9;
                }
            }
            return 10;
        }

        public int Deposit(string token, long amount)
        {
            var sercurity = new SercurityDAO();
            bool isExpire = sercurity.ValidateToken(token);
            if (!isExpire)
            {
                string id = sercurity.GetIdByToken(token);
                using (_context = Common.Utils.GetObjectContext())
                {
                    var result = _context.Customer.FirstOrDefault(customer => customer.CustomerID.Equals(id));
                    if (result != null)
                    {
                        result.Balance = result.Balance + amount;
                        _context.SaveChanges();
                        return 0;
                    }
                    return 9;
                }
            }
            return 10;
        }

        public int Transfer(string token, string receiverId, long amount)
        {
            var sercurity = new SercurityDAO();
            bool isExpire = sercurity.ValidateToken(token);
            if (!isExpire)
            {
                string id = sercurity.GetIdByToken(token);
                using (_context = Common.Utils.GetObjectContext())
                {
                    var result = _context.Customer.FirstOrDefault(customer => customer.CustomerID.Equals(id));
                    {
                        if (result != null)
                        {
                            if (!CheckId(receiverId))
                            {
                                return 7;
                            }
                            if ((result.Balance - amount) < 50)
                            {
                                return 8;
                            }
                            result.Balance = result.Balance - amount;
                            try
                            {
                                _context.SaveChanges();
                            }
                            catch (Exception)
                            {
                                return 9;
                            }

                            var isSuccess = Transferer(receiverId, amount);
                            return isSuccess ? 0 : 9;
                        }
                        return 9;
                    }
                }
            }
            return 10;
        }

        private bool Transferer (string id, long amount)
        {
            ATMServiceEntities context;
            using (context = Common.Utils.GetObjectContext())
            {
                var result = context.Customer.FirstOrDefault(customer => customer.CustomerID.Equals(id));
                if (result != null)
                {
                    result.Balance = result.Balance + amount;
                    context.SaveChanges();
                    return true;
                }
                return false;
            }
        }
        private bool CheckId(string id)
        {
            ATMServiceEntities context;
            using (context = Common.Utils.GetObjectContext())
            {
                var result = context.Customer.FirstOrDefault(customer => customer.CustomerID.Equals(id));
                if (result != null)
                    {
                     return true;   
                    }
                    return false;
            }
        }

        public bool AccountBlocking(string id)
        {
            ATMServiceEntities context;
            using (context = Common.Utils.GetObjectContext())
            {
                var result = context.Customer.FirstOrDefault(customer => customer.CustomerID.Equals(id));
                if (result!= null)
                {
                    result.Status = "Blocked";
                    context.SaveChanges();
                    return true;
                }
                return false;
            }
        }

        public string ViewBalance(string token)
        {
            var sercurity = new SercurityDAO();
            bool isExpire = sercurity.ValidateToken(token);
            if (!isExpire)
            {
                string id = sercurity.GetIdByToken(token);
                using (_context = Common.Utils.GetObjectContext())
                {
                    var result = _context.Customer.FirstOrDefault(customer => customer.CustomerID.Equals(id));
                    {
                        if (result != null)
                        {
                            try
                            {
                                return Convert.ToString(result.Balance);
                            }
                            catch (Exception e)
                            {
                                return null;
                            }
                        }
                        return null;
                    }
                }
            }
            return null;
        }
    }
}